﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Xml;
using Microsoft.Xrm.Sdk;
using SolutionExtender.Controls;
using SolutionExtender.Interfaces;

namespace McTools.SolutionExtender.CustomEntitiesRecordsPlugin
{
    public class CustomEntitiesRecordsConnector : IConnector
    {
         #region Variables

        /// <summary>
        /// IOrganization service to access CRM 2011 data
        /// </summary>
        private readonly IOrganizationService _service;

        #endregion Variables

        #region Constructor

        /// <summary>
        /// Initializes a new instance of class DuplicateRuleConnector
        /// </summary>
        /// <param name="service">IOrganization service to access CRM 2011 data</param>
        public CustomEntitiesRecordsConnector(IOrganizationService service)
        {
            _service = service;
        }

        #endregion Constructor

        public string ObjectName
        {
            get { return "Custom entities records"; }
        }

        public string Description
        {
            get { return "Allows to export custom entities records"; }
        }

        public List<ImportResult> Import(XmlNode data)
        {
            var importResults = new List<ImportResult>();

            if(data.FirstChild == null)
                return null;

            var dataNode = data.FirstChild;

            foreach (XmlNode buNode in dataNode.ChildNodes)
            {
                Entity record;

                var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(buNode.OuterXml));

                using (var reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.UTF8,
                                                                         new XmlDictionaryReaderQuotas(), null))
                {

                    var serializer = new DataContractSerializer(typeof(Entity),
                                                                null,
                                                                int.MaxValue,
                                                                false,
                                                                false,
                                                                null,
                                                                new KnownTypesResolver());

                    record = (Entity)serializer.ReadObject(reader);
                }

                try
                {
                    try
                    {
                        if (record.Contains("ownerid"))
                            record.Attributes.Remove("ownerid");

                        _service.Create(record);
                    }
                    catch (Exception error)
                    {
                        if (error.Message.IndexOf("insert duplicate key") >= 0) 
                        {
                            if (record.Contains("ownerid"))
                                record.Attributes.Remove("ownerid");
                            _service.Update(record);
                        }
                        else
                        {
                            importResults.Add(new ImportResult
                            {
                                Message = error.Message,
                                Succeed = false,
                                Type = ObjectName + " : " + record.LogicalName,
                                Name = record[buNode.ParentNode.Attributes["primaryAttribute"].Value].ToString()
                            });
                        }
                    }

                    importResults.Add(new ImportResult
                    {
                        Message = string.Empty,
                        Succeed = true,
                        Type = ObjectName + " : " + record.LogicalName,
                        Name = record[buNode.ParentNode.Attributes["primaryAttribute"].Value].ToString()
                    });
                }
                catch (Exception error)
                {
                    importResults.Add(new ImportResult
                    {
                        Message = error.Message,
                        Succeed = false,
                        Type = ObjectName + " : " + record.LogicalName,
                        Name = record[buNode.ParentNode.Attributes["primaryAttribute"].Value].ToString()
                    });
                }
            }

            return importResults;
        }

        public IExportControl GetExportControl(IOrganizationService service)
        {
            return new CustomEntitiesRecordControl(service);
        }

        public string GetRecordName(XmlNode node)
        {
            return "CustomEntitiesRecords";
        }
    }
}
